package com.king.base.auth.rest;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.IdUtil;
import com.king.base.auth.security.AuthenticationToken;
import com.king.base.auth.security.AuthorizationUser;
import com.king.base.auth.security.ImgResult;
import com.king.base.auth.security.JwtUser;
import com.king.base.auth.service.OnlineService;
import com.king.base.auth.service.PermissionService;
import com.king.base.auth.utils.EncryptUtils;
import com.king.base.auth.utils.JwtTokenUtil;
import com.king.base.msg.BaseResponseEntity;
import com.king.base.utils.StringUtils;
import com.king.base.utils.VerifyCodeUtils;
import com.king.base.service.redis.RedisService;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import static org.springframework.http.HttpStatus.BAD_REQUEST;

/**
 * @author TianYZ
 * @date 2019-06-15
 * 授权、根据token获取用户详细信息
 */
@RestController
@RequestMapping("auth")
public class AuthenticationController {

    @Value("${project.name}")
    private String projectName;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    @Qualifier("jwtUserDetailsService")
    private UserDetailsService userDetailsService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private PermissionService permissionService;
    @Autowired
    private OnlineService onlineService;

    @GetMapping(value = "/sys/config")
    public BaseResponseEntity config(HttpServletRequest request){
        return new BaseResponseEntity(projectName);
    }

    /**
     * 登录授权
     * @param authorizationUser
     * @return
     */
    @PostMapping(value = "${jwt.auth.path}")
    public BaseResponseEntity authenticationLogin(@RequestBody AuthorizationUser authorizationUser, HttpServletRequest request){

        if(authorizationUser.isNeedAuthCode()){
            // 查询验证码
            String code = redisService.getCodeVal(authorizationUser.getUuid());
            // 清除验证码
            redisService.delete(authorizationUser.getUuid());
            if (StringUtils.isBlank(code)) {
                return new BaseResponseEntity(BAD_REQUEST.value(),"验证码已过期");
            }
            if (StringUtils.isBlank(authorizationUser.getCode()) || !authorizationUser.getCode().equalsIgnoreCase(code)) {
                return new BaseResponseEntity(BAD_REQUEST.value(),"验证码错误");
            }
        }
        final JwtUser jwtUser =(JwtUser) userDetailsService.loadUserByUsername(authorizationUser.getLoginName());

        if(!jwtUser.getPassword().equals(EncryptUtils.encryptPassword(authorizationUser.getPassword()))){
            return new BaseResponseEntity(BAD_REQUEST.value(),"密码错误");
        }

        if("1".equals(jwtUser.getStatus())){
            return new BaseResponseEntity(BAD_REQUEST.value(),"账号已停用，请联系管理员");
        }

        // 生成令牌
        final String token = jwtTokenUtil.generateToken(jwtUser);
        // 保存在线信息
        onlineService.save(jwtUser, token, request);
        return new BaseResponseEntity(new AuthenticationToken(token,jwtUser));
    }

    /**
     * 获取用户信息
     * @param request
     * @return
     */
    @GetMapping(value = "${jwt.auth.account}")
    public BaseResponseEntity getUserInfo(HttpServletRequest request){
        JwtUser jwtUser = (JwtUser)userDetailsService.loadUserByUsername(jwtTokenUtil.getLoginName(request));
        Set<String> roles=permissionService.getUserRoles(jwtUser.getUserId());
        Set<String> permissions=permissionService.getUserMenuPermission(jwtUser.getUserId());
        Map<String,Object> map=new HashMap<>();
        map.put("user",jwtUser);
        map.put("roles",roles);
        map.put("permissions",permissions);
        return new BaseResponseEntity(map);
    }

    /**
     * 获取验证码
     */
    @GetMapping(value = "vCode")
    public ImgResult getCode(HttpServletResponse response) throws IOException {
        //生成随机字串
        String verifyCode = VerifyCodeUtils.generateVerifyCode(4);
        String uuid = IdUtil.simpleUUID();
        redisService.saveCode(uuid,verifyCode);
        // 生成图片
        int w = 111, h = 36;
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        VerifyCodeUtils.outputImage(w, h, stream, verifyCode);
        try {
            return new ImgResult(Base64.encode(stream.toByteArray()),uuid);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            stream.close();
        }
    }
    @ApiOperation("退出登录")
    @PostMapping(value = "/logout")
    public BaseResponseEntity logout(HttpServletRequest request){
        onlineService.logout(jwtTokenUtil.getToken(request));
        return new BaseResponseEntity(HttpStatus.OK.value(),"退出成功!");
    }
}
